package org.example.MedicalCrowdsourcing.controller;

import org.example.MedicalCrowdsourcing.dto.LoginRequest;
import org.example.MedicalCrowdsourcing.dto.LoginResponse;
import org.example.MedicalCrowdsourcing.dto.PasswordChangeRequest;
import org.example.MedicalCrowdsourcing.dto.RegisterRequest;
import org.example.MedicalCrowdsourcing.dto.UserDto;
import org.example.MedicalCrowdsourcing.model.entity.Role;
import org.example.MedicalCrowdsourcing.model.entity.User;
import org.example.MedicalCrowdsourcing.repository.RoleRepository;
import org.example.MedicalCrowdsourcing.security.JwtUtils;
import org.example.MedicalCrowdsourcing.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 */
@RestController
@RequestMapping("/api/medical-crowdsourcing/auth")
@CrossOrigin(origins = "http://localhost:8081", allowCredentials = "true")
public class AuthController {
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private HttpServletRequest request;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public ResponseEntity<LoginResponse> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.getUsername(),
                        loginRequest.getPassword()
                )
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateJwtToken(authentication);
        
        // 获取用户信息
        User user = userService.findByUsername(loginRequest.getUsername())
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 记录登录信息
        userService.recordLogin(user, request, true);
        
        // 构建响应对象
        LoginResponse response = LoginResponse.builder()
                .token(jwt)
                .type("Bearer")
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .role(user.getRole().getName())
                .blockchainAddress(user.getBlockchainAddress())
                .build();
        
        return ResponseEntity.ok(response);
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public ResponseEntity<UserDto> registerUser(@Valid @RequestBody RegisterRequest registerRequest) {
        // 检查用户名是否已存在
        if (userService.existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (userService.existsByEmail(registerRequest.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }

        // 注册用户
        User user = userService.registerUser(
                registerRequest.getUsername(),
                registerRequest.getEmail(),
                registerRequest.getPassword(),
                registerRequest.getRole(),
                registerRequest.getBlockchainAddress()
        );

        // 构建用户DTO
        UserDto userDto = UserDto.builder()
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .role(user.getRole().getName())
                .blockchainAddress(user.getBlockchainAddress())
                .createdAt(user.getCreatedAt())
                .build();

        return new ResponseEntity<>(userDto, HttpStatus.CREATED);
    }
    
    /**
     * 修改密码
     */
    @PostMapping("/change-password")
    public ResponseEntity<?> changePassword(@Valid @RequestBody PasswordChangeRequest request) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        
        User user = userService.findByUsername(userDetails.getUsername())
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 验证当前密码
        if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) {
            Map<String, String> response = new HashMap<>();
            response.put("message", "当前密码不正确");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
        }
        
        // 更新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        userService.save(user);
        
        Map<String, String> response = new HashMap<>();
        response.put("message", "密码修改成功");
        return ResponseEntity.ok(response);
    }

    /**
     * 验证JWT令牌
     */
    @PostMapping("/validate-token")
    public ResponseEntity<?> validateToken(@RequestHeader("Authorization") String authHeader) {
        try {
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                String jwt = authHeader.substring(7);
                
                if (jwtUtils.validateJwtToken(jwt)) {
                    // 提取用户名并获取用户数据
                    String username = jwtUtils.getUserNameFromJwtToken(jwt);
                    User user = userService.findByUsername(username)
                            .orElseThrow(() -> new RuntimeException("用户不存在"));
                    
                    // 构建用户DTO
                    UserDto userDto = UserDto.builder()
                            .id(user.getId())
                            .username(user.getUsername())
                            .email(user.getEmail())
                            .role(user.getRole().getName())
                            .blockchainAddress(user.getBlockchainAddress())
                            .createdAt(user.getCreatedAt())
                            .lastLogin(user.getLastLogin())
                            .build();
                    
                    Map<String, Object> response = new HashMap<>();
                    response.put("valid", true);
                    response.put("user", userDto);
                    
                    return ResponseEntity.ok(response);
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("valid", false);
            response.put("message", "无效的令牌");
            
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("valid", false);
            response.put("message", "令牌验证失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
        }
    }

    /**
     * 初始化角色
     */
    @PostMapping("/init-roles")
    public ResponseEntity<String> initRoles() {
        // 创建角色
        if (roleRepository.count() == 0) {
            // 使用三参数构造器，第三个参数为描述
            roleRepository.save(new Role(Role.ADMIN, "ROLE_ADMIN", "管理员角色"));
            roleRepository.save(new Role(Role.RESEARCHER, "ROLE_RESEARCHER", "研究者角色"));
            roleRepository.save(new Role(Role.PARTICIPANT, "ROLE_PARTICIPANT", "参与者角色"));
            return ResponseEntity.ok("角色初始化成功");
        }
        return ResponseEntity.ok("角色已存在，无需初始化");
    }
} 